package com.c1.client.pan;

import com.s.core.root.Ad;
import com.s.core.root.data.*;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import javax.swing.*;
import java.awt.*;
import java.math.BigDecimal;

/**
 * @author zhangjiangnan
 */
@Getter
@Setter
@Slf4j
public class Pan extends JPanel {
    public Pan(_AllData allData, int titleNumberIndex) {
        this.allData = allData;
        fatherScrollPan = new JScrollPane(this);
        this.titleNumberIndex = titleNumberIndex;
    }

    private JScrollPane fatherScrollPan;

    private _AllData allData;
    private int titleNumberIndex;
    private boolean showMode;

    public String code(boolean allowNull) {
        if (allData == null && allowNull) {
            return null;
        }
        if (allData == null) {
            throw new RuntimeException();
        }
        return allData.d.code;
    }

    public String date(boolean allowNull) {
        if (allData == null && allowNull) {
            return Ad.me().getDateList().get(0);
        }
        if (allData == null) {
            throw new RuntimeException();
        }
        return allData.d.date;
    }

    public int getPicNNextIndex() {
        return allData.picNMap.get(2).getShowIndex();
    }

    public int getPicNextIndex() {
        return allData.pic.getShowIndex();
    }

    public void setPicNNextIndex(int index) {
        for (int n : allData.picNMap.keySet()) {
            _PicN picN = allData.picNMap.get(n);
            picN.setShowIndex(index);
        }
    }

    public void setPicNextIndex(int index) {
        allData.pic.setShowIndex(index);
    }

    public void posNNextIndex() {
        for (int n : allData.picNMap.keySet()) {
            _PicN picN = allData.picNMap.get(n);
            picN.nextShowIndex();
        }
    }

    public void picNextIndex() {
        allData.pic.nextShowIndex();
    }

    @Override
    public void paintComponent(Graphics g) {
        try {
            Thread.sleep(50);
        } catch (InterruptedException ignored) {
        }
        if (allData != null) {
            setPreferredSize(paintAllData(g));
        }
        revalidate();
        fatherScrollPan.setBackground(new Color(Integer.parseInt(globalStyle().panBak, 16)));
        fatherScrollPan.updateUI();
    }

    private Dimension paintAllData(Graphics g) {
        int width = 0;
        int height = 0;
        int contentY = 0;

        contentY += globalStyle().up;
        height += globalStyle().up;

        _BasePic[][] allPics = new _BasePic[][]{
                new _BasePic[]{allData.pic},
                new _BasePic[]{allData.picNMap.get(2), allData.picNMap.get(3)},
                new _BasePic[]{allData.picNMap.get(4), allData.picNMap.get(5), allData.picNMap.get(6)},
                new _BasePic[]{allData.picNMap.get(7), allData.picNMap.get(8), allData.picNMap.get(9), allData.picNMap.get(10)},
                new _BasePic[]{allData.picNMap.get(11), allData.picNMap.get(12), allData.picNMap.get(13), allData.picNMap.get(14)},
        };

        _BasePic[][] allPics2 = new _BasePic[][]{
                new _BasePic[]{allData.picNMap.get(15), allData.picNMap.get(16), allData.picNMap.get(17), allData.picNMap.get(18)},
                new _BasePic[]{allData.picNMap.get(19), allData.picNMap.get(20), allData.picNMap.get(21), allData.picNMap.get(22)},
                new _BasePic[]{allData.picNMap.get(23), allData.picNMap.get(24), allData.picNMap.get(25)},
        };

        for (_BasePic[] pics : showMode ? allPics2 : allPics) {
            int addH = 0;
            int contentX = 0;
            int w = 0;
            for (_BasePic pic : pics) {
                int[] widthHeight = paintPic(g, contentX, contentY, pic);
                if (widthHeight[1] > addH) {
                    addH = widthHeight[1];
                }
                w += widthHeight[0];
                contentX += widthHeight[0];
            }
            contentY += addH + globalStyle().picsInner;
            height += addH + globalStyle().picsInner;
            if (w > width) {
                width = w;
            }
        }
        return new Dimension(width, height);
    }

    private int[] paintPic(Graphics g, int x, int y, _BasePic pic) {
        final int contentWidth = globalStyle().xPerWidth * pic.getPointList().size();
        final int width = contentWidth + 2 * globalStyle().lRMargin;
        final int contentX = x + globalStyle().lRMargin;

        int contentY = y;
        int volPicHeight = drawVol(g, pic, contentX, contentY, contentWidth);

        contentY += volPicHeight + globalStyle().posCjlInter;
        int posPicHeight = drawPos(g, pic, contentX, contentY, contentWidth);
        return new int[]{width, volPicHeight + posPicHeight + globalStyle().posCjlInter};
    }

    private int drawPos(Graphics g, _BasePic pic, int contentX, int contentY, int contentWidth) {
        //排名边界
        DrawUtil.drawRect(contentX, contentY, contentWidth, globalStyle().picHeight, g,
                conf().borderStyle.c, conf().borderStyle.alpha, conf().borderStyle.stroke, false, 1);

        //排名分割线
        for (int i = 1; i <= 4; i++) {
            DrawUtil.drawRect(contentX, contentY + globalStyle().picHeight * i / 5 - 2, contentWidth, 2,
                    g, conf().boundaryStyle.c, conf().boundaryStyle.alpha, -1, true, 1);
        }
        return globalStyle().picHeight + drawPos(g, contentX, contentY, pic);
    }

    private int drawVol(Graphics g, _BasePic pic, int contentX, int contentY, int contentWidth) {
        //量底边
        DrawUtil.drawLine(g, contentX, contentY + globalStyle().picHeight, contentX + contentWidth, contentY + globalStyle().picHeight,
                conf().borderStyle.c, conf().borderStyle.stroke, true, conf().borderStyle.alpha);
        //量柱
        int xSign = contentX;
        for (int i = 0; i < pic.getPointList().size(); i++) {
            _BasePoint point = pic.getPointList().get(i);
            if (!point.isTp()) {
                int cHeight = Math.toIntExact((long) globalStyle().picHeight * point.vol().longValue() / pic.getMaxVol());
                PanConf.CjlStyle cs = point.cjlStyle();
                int cW = globalStyle().xPerWidth - cs.integer;
                DrawUtil.drawRect(xSign, contentY + globalStyle().picHeight, cW, cHeight, g, cs.c, cs.alpha, -1, true, 5);
            }
            xSign += globalStyle().xPerWidth;
        }
        return globalStyle().picHeight;
    }

    private int drawPos(Graphics g, int contentX, int contentY, _BasePic pic) {
        int result = 0;
        int[] preSign = null;
        int xSign = contentX;
        for (int i = 0; i < pic.getPointList().size(); i++) {
            _BasePoint point = pic.getPointList().get(i);
            if (point.isTp()) {
                xSign += globalStyle().xPerWidth;
                continue;
            }
            int ySign = contentY + new BigDecimal(globalStyle().picHeight).multiply(BigDecimal.valueOf(point.rate())).intValue();

            PanConf.PosStyle ps = point.posStyle();
            DrawUtil.drawOval(g, xSign, ySign, ps.w, ps.c, ps.stroke, ps.solid, ps.alpha);

            _BasePoint.InfoAndStyle yIs = point.yInfo();
            if (yIs != null) {
                DrawUtil.drawString(yIs.info, g, xSign, ySign, null,
                        yIs.infoStyle.style, yIs.infoStyle.size, yIs.infoStyle.c, 5, yIs.infoStyle.alpha);
            }

            if (preSign != null) {
                drawLinePos(g, preSign[0], preSign[1], xSign, ySign);
            }
            _BasePoint.InfoAndStyle xIs = point.xInfo();
            if (xIs != null) {
                int[] wh = DrawUtil.drawString(xIs.info, g, xSign, contentY + globalStyle().picHeight,
                        null, xIs.infoStyle.style, xIs.infoStyle.size, xIs.infoStyle.c, 5, xIs.infoStyle.alpha);
                result = wh[1];
            }
            preSign = new int[]{xSign, ySign};
            xSign += globalStyle().xPerWidth;
        }
        return result;
    }

    private void drawLinePos(Graphics g, int x, int y, int x1, int y1) {
        DrawUtil.drawLine(g, x, y, x1, y1,
                conf().lineStyle.c, conf().lineStyle.stroke, true, conf().lineStyle.alpha);
    }

    private PanConf conf() {
        return PanConf.me();
    }

    private PanConf.GlobalStyle globalStyle() {
        return conf().globalStyle;
    }
}